package com.mhc.suzuki.service.impl;


import com.alibaba.fastjson.JSON;
import com.mhc.fiat.api.ProcessServiceWraper;
import com.mhc.fiat.api.ResolveProcessParametersHandler;
import com.mhc.fiat.api.domain.ProcessVariable;
import com.mhc.haval.api.dto.AuditQuotaDTO;
import com.mhc.haval.api.dto.DeptBizAreaDTO;
import com.mhc.haval.api.dto.StaffRoleDTO;
import com.mhc.haval.api.dto.WorkflowDTO;
import com.mhc.haval.api.service.IAuditQuotaService;
import com.mhc.haval.api.service.IStaffDeptService;
import com.mhc.haval.api.service.IStaffRoleService;
import com.mhc.haval.api.service.WorkFlowConfigService;
import com.mhc.haval.security.model.DeptArea;
import com.mhc.haval.security.model.User;
import com.mhc.suzuki.bo.OrderInfoBO;
import com.mhc.suzuki.bo.ProcessParamBO;
import com.mhc.suzuki.bo.SubmitTaskBO;
import com.mhc.suzuki.constant.*;
import com.mhc.suzuki.dal.mapper.OrderAuditTaskMapper;
import com.mhc.suzuki.dal.mapper.ext.LoanInfoExtMapper;
import com.mhc.suzuki.dal.mapper.ext.OrderAuditTaskExtMapper;
import com.mhc.suzuki.dal.model.*;
import com.mhc.suzuki.dal.query.*;
import com.mhc.suzuki.exception.SuzukiCommonException;
import com.mhc.suzuki.manager.*;
import com.mhc.suzuki.service.*;
import com.mhc.suzuki.util.Constant;
import com.mhc.suzuki.util.DateUtil;
import com.mhc.suzuki.vo.DateRangeVO;
import com.mhc.suzuki.vo.PaymentRequestVO;
import com.mhc.suzuki.vo.WanderResultVO;
import com.subaru.common.entity.BizResult;
import com.subaru.common.enums.ordercenter.FpUserTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by HMJ on 2017/8/22.
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class ApplyServiceImpl implements ApplyService {

    @Autowired
    private WorkFlowConfigService workFlowConfigService;
//    @Autowired
//    private ProcessServiceWraper processServiceWraper;
    @Autowired
    private OrderAuditTaskExtMapper orderAuditTaskExtMapper;
    @Autowired
    private IStaffRoleService staffRoleService;
    @Autowired
    private IStaffDeptService staffDeptService;
    @Autowired
    private OrderAuditApplyService orderAuditApplyService;
    @Autowired
    private OrderAuditTaskMapper orderAuditTaskMapper;
    @Autowired
    private OrderAuditApplyManager orderAuditApplyManager;
    @Autowired
    private OrderManager orderManager;
    @Autowired
    private CarInfoManager carInfoManager;
    @Autowired
    private PaymentRequestService paymentRequestService;
    @Autowired
    private ContractSubmitManager contractSubmitManager;
    @Autowired
    private LoanInfoExtMapper loanInfoExtMapper;
    @Autowired
    private MessageService messageService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private IAuditQuotaService iAuditQuotaService;
    @Autowired
    private ProvinceManager provinceManager;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 发起申请流程 -- 公共代码
     * @param submitTaskBO
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean startApply(SubmitTaskBO submitTaskBO, User logedUser) throws SuzukiCommonException {
        /**获取员工信息**/
        log.info("正在获取当前员工信息...");
        log.info("当前的员工信息：{} ,{}" ,logedUser.getStaffId(), logedUser.getStaffName());
        /**新增申请数据**/
        long applyId = orderAuditApplyService.addOrderAuditApply(submitTaskBO, logedUser);   //返回获取申请编号
        /**根据员工所属部门ID查找所属流程**/
        WorkflowDTO workflow = workFlowConfigService.selectWorkFlow(logedUser.getCompanyNo(), submitTaskBO.getApplyType());
        if (workflow != null && StringUtils.isNotEmpty(workflow.getFlowTempId())) {
            log.info("开始调用工作流为：{},流程编号为：{}" ,workflow.getFlowName(), workflow.getFlowTempId());
            /**调用工作流启动流程**/
            ProcessParamBO processParamBO = new ProcessParamBO();
            processParamBO.setStaffId(String.valueOf(logedUser.getStaffId()));           //发起者编号
            processParamBO.setProcessId(workflow.getFlowTempId());                       //流程编号
            processParamBO.setBusinessKey(submitTaskBO.getOrderNo());                    //订单号
            processParamBO.setBizType(submitTaskBO.getBizType());                        //业务类型
            processParamBO.setLoanMoney(submitTaskBO.getLoanMoney());                    //贷款金额
            processParamBO.setApplyId(String.valueOf(applyId));                          //申请编号
            processParamBO.setApplyType(String.valueOf(submitTaskBO.getApplyType()));    //申请类型
            processParamBO.setGpsFlag(submitTaskBO.getNeedGps());                        //GPS确认标识
            processParamBO.setIsCashIn(submitTaskBO.getIsCashIn());                      //垫款标识符
            BizResult<String> result = this.startWorkflow(processParamBO,logedUser);
            if (result.getData() != null) {
                log.info("正在更新申请数据...");
                OrderAuditApplyDO record = new OrderAuditApplyDO();
                record.setApplyId(applyId);           //申请ID
                record.setFlowInstanceId(result.getData());    //流程实例ID
                orderAuditApplyManager.updateByPrimaryKeySelective(record);
                log.info("更新申请数据完成...");
                log.info("调用流程成功，返回流程实例为：{}", result.getData());
                return true;
            }
            throw new SuzukiCommonException(ErrorCodeEnum.FLOW_INST_CREATE_FAIL);
        }
        throw new SuzukiCommonException(ErrorCodeEnum.SELECT_FAILURE);
    }

    /**
     * 提交审核信息
     * @param submitTaskBO
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean saveOrderAudit(SubmitTaskBO submitTaskBO, User logedUser) throws SuzukiCommonException {
        log.info("正在保存审核信息...");
        OrderAuditTaskDO record = new OrderAuditTaskDO();
        OrderAuditTaskQuery query = new OrderAuditTaskQuery();
        /**获取审核意见**/
        int approvalResult = submitTaskBO.getApprovalResult();   //获取审核意见
        log.info("当前审核意见为：{}", ApprovalResultEnum.getApprovalResultEnum(approvalResult).getName());
        log.info("开始插入审批数据...");
        if(submitTaskBO.getApproveStaffId()!=null && submitTaskBO.getApproveStaffName()!=null){
            record.setApproveStaffId(submitTaskBO.getApproveStaffId());
            record.setApproveStaffName(submitTaskBO.getApproveStaffName());
        }
        record.setCustomerAnalysis(submitTaskBO.getCustomerAnalysis());
        record.setApprovalResult(approvalResult);
        record.setApprovalRemark(submitTaskBO.getApprovalRemark());
        record.setApprovalTime(LocalDateTime.now());
        record.setTaskStatus(TaskStatusEnum.HANDLED.getCode());
        record.setConditionalPass(submitTaskBO.getConditionalPass());
        query.createCriteria().andTaskIdEqualTo(submitTaskBO.getTaskId());
        orderAuditTaskMapper.updateByQuerySelective(record, query);
        log.info("插入审批数据完成...");
        /**任何审核环节审核不通过**/
        if(ApprovalResultEnum.REJECT.getCode().equals(approvalResult) || ApprovalResultEnum.PARTPASS.getCode().equals(approvalResult)){
            if(ApplyTypeEnum.PAYMENT_REQUEST_APPLY.getCode().equals(submitTaskBO.getApplyType())){
                /**打款申请时为垫款驳回**/
                orderService.changeOrderStatus(submitTaskBO.getOrderNo(),OrderStatusEnum.PAYMENT_REQUEST_REJECT.getCode());   //垫款驳回
            }else {
                /**其他为贷款审核未通过**/
                orderService.changeOrderStatus(submitTaskBO.getOrderNo(),OrderStatusEnum.APPLICATION_IN_NOT_APPROVED.getCode());  //贷款审核未通过
            }
        }
        /**提交流程**/
        log.info("开始提交流程...");
        ProcessParamBO processParamBO = new ProcessParamBO();
        processParamBO.setApproved(String.valueOf(approvalResult));
        processParamBO.setLoanMoney(submitTaskBO.getLoanMoney());
        Boolean taskFlag = this.submitWorkflow(logedUser, submitTaskBO.getFlowNodeId(), processParamBO);
        if (taskFlag!=null && taskFlag) {
            log.info("提交成功...");
            /**提交成功，发送消息**/
            try {
                if (ApprovalResultEnum.REJECT.getCode().equals(approvalResult)) {//审核不通过，且不为，发送审核不通过消息
                    log.info("审核不通过，消息发送到业务员");
                    //获取对应订单号
                    OrderAuditTaskDO orderAuditTaskDO = orderAuditTaskExtMapper.selectByPrimaryKey(submitTaskBO.getTaskId());
                    String orderNo = orderAuditTaskDO.getOrderNo();
                    OrderQuery orderQuery = new OrderQuery();
                    orderQuery.createCriteria().andOrderNoEqualTo(orderNo)
                            .andOrderStatusNotEqualTo(OrderStatusEnum.CANCELLED.getCode());
                    List<OrderDO> orderDOS = orderManager.selectByQuery(orderQuery);
                    if (orderDOS.size() != 1){
                        log.info("数据异常");
                        throw new SuzukiCommonException(ErrorCodeEnum.DATA_ERROR);
                    }
                    OrderDO orderDO = orderDOS.get(0);
                    messageService.sendNoPassMessage(orderDO, submitTaskBO);
                }
            } catch (IOException e){
                log.error("IOException", e);
            }
            return true;
        }
        throw new SuzukiCommonException(ErrorCodeEnum.AUDIT_ERROR);    //提交审核错误
    }




    /**
     * 启动流程
     * @param processParamBO
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    private BizResult<String> startWorkflow(ProcessParamBO processParamBO,User logedUser) throws SuzukiCommonException{
        BizResult<String> bizResult = null;
        try {
//            bizResult = processServiceWraper.startProcess(processParamBO.getStaffId(), FpUserTypeEnum.YUANTONG.getCode(),
//                    processParamBO.getBusinessKey(), processParamBO.getProcessId(), new ResolveProcessParameters(processParamBO, logedUser));
            log.info("提交反馈:{}", JSON.toJSONString(bizResult));
        }catch (Exception e){
            log.error("工作流提交流程报错", e);
            throw new SuzukiCommonException(ErrorCodeEnum.APPLY_ERROR);
        }
        return bizResult;
    }

    /**
     * 提交流程
     * @param logedUser
     * @param taskId
     * @param processParamBO
     * @return
     * @throws SuzukiCommonException
     */
    private Boolean submitWorkflow(User logedUser,String taskId,ProcessParamBO processParamBO) throws SuzukiCommonException {
        /**1、获取当前登陆人**/
        String staffId = String.valueOf(logedUser.getStaffId());
        /**根据审核结果判断true或false**/
        boolean submitResult = true;
        if ((processParamBO.getApproved()).equals(ApprovalResultEnum.REJECT.getCode().toString())) {
            /**当页面传值等于'0'时，为false**/
            submitResult = false;
        }
        try {
//            BizResult<Boolean> bizResult = processServiceWraper.completeActTask(staffId, FpUserTypeEnum.YUANTONG.getCode(),
//                    taskId, submitResult, null, new ResolveProcessParameters(processParamBO,logedUser));
            BizResult<Boolean> bizResult = new BizResult();
            log.info("提交反馈：{}", JSON.toJSONString(bizResult));
            return bizResult.getData();
        }catch (Exception e){
            if(("org.activiti.engine.ActivitiObjectNotFoundException").equals(e.getMessage().substring(0,e.getMessage().indexOf(":")))){
                log.info("该流程任务已被提交...");
                throw new SuzukiCommonException(ErrorCodeEnum.TASK_HAS_HANDLE);
            }
        }
        return false;
    }


    /**
     * 通过审核结果判断是否查找新执行人
     * @param approved
     * @param processVariable
     * @param resolveParameters
     * @param roleStr
     * @param logedUser
     */
    private void randomExecutorByApproved(String approved, ProcessVariable processVariable, Map<String, Object> resolveParameters, String roleStr,User logedUser){
        try {
            if(StringUtils.isBlank(approved)){
                /**当审核结果无信息，即发起查找新执行人**/
                String nextStaffId = this.randomExecutor(roleStr,logedUser);
                resolveParameters.put(processVariable.getId(), nextStaffId);
            }else {
                if (approved.equals(ApprovalResultEnum.REJECT.getCode().toString())) {
                    /**当审核被拒绝时，无需查找新执行人**/
                    resolveParameters.put(processVariable.getId(), null);
                } else {
                    /**当审核结果通过时,需判断下一节点是否之前执行过，如果是，则无需查找新执行人；如果不是，则查找新执行人**/
                    if (processVariable.getValue() != null) {
                        resolveParameters.put(processVariable.getId(), processVariable.getValue());
                    } else {
                        String nextStaffId = this.randomExecutor(roleStr,logedUser);
                        resolveParameters.put(processVariable.getId(), nextStaffId);
                    }
                }
            }
        } catch (SuzukiCommonException e) {
            log.error("获取执行人异常", e);
        }
    }


    /**
     * 检查是否可以发起打款申请
     * @param submitTaskBO
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean isPayMentApply(SubmitTaskBO submitTaskBO, User logedUser) throws SuzukiCommonException {
        log.info("正在验证车辆GPS是否需要安装...");
        /**2、判断是否有安装GPS:查询车辆信息表看字段是否存在**/
        boolean gpsFlag = false;  //默认为不安装GPS
        CarInfoQuery carInfoQuery = new CarInfoQuery();
        carInfoQuery.createCriteria().andOrderNoEqualTo(submitTaskBO.getOrderNo());       //根据订单号查询车辆信息表的GPS信息
        List<CarInfoDO> carInfo = carInfoManager.selectByQuery(carInfoQuery);
        if (!CollectionUtils.isEmpty(carInfo)) {
            /**存在数据且只有一条**/
            Boolean isgps = carInfo.get(0).getNeedGps();     //获取gps是否安装
            if (GpsEnum.NEED.getCode().equals(isgps)) {
                /**需要安装GPS，查询GPS编号是否填写**/
                log.info("需要安装GPS...");
                String gpsNum = carInfo.get(0).getGpsNum();  //获取GPS编号
                if (!StringUtils.isBlank(gpsNum)) {
                    log.info("存在GPS编号：{}", gpsNum);
                    gpsFlag = true;
                    return gpsFlag;
                } else {
                    throw new SuzukiCommonException(ErrorCodeEnum.GPS_INFO_EMPTRY);    //GPS编号为空，请补全资料
                }
            } else {
                /**不需要安装GPS**/
                log.info("不需要安装GPS...");
                return gpsFlag;
            }
        }
        throw new SuzukiCommonException(ErrorCodeEnum.SELECT_FAILURE);
    }

    /**
     * 查看订单状态判断执行流程类型
     * @param orderNo
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean isOrderStatusByApproved(String orderNo) throws SuzukiCommonException {
        int orderStatus = orderService.selectOrderStatus(orderNo);
        /**拼装审核前的状态**/
        List<Object> noApprovedList = new ArrayList();
        noApprovedList.add(OrderStatusEnum.CREDITING.getCode());    //征信结果待录入
        noApprovedList.add(OrderStatusEnum.CREDIT_HAS_BEEN_RECORDER.getCode());  //征信结果已录入
        noApprovedList.add(OrderStatusEnum.APPLICATION_IN_NOT_APPROVED.getCode());  //贷款审核未通过
        noApprovedList.add(OrderStatusEnum.UPDATE_CREDITING.getCode());  //修改征信结果待录入
        noApprovedList.add(OrderStatusEnum.UPDATE_HAS_BEEN_RECORDER.getCode());  //修改征信结果已录入
        Boolean approvedFlag = Boolean.TRUE;   //默认审核后
        for (int i = 0; i < noApprovedList.size(); i++) {
            if (noApprovedList.get(i).equals(orderStatus)) {
                log.info("审核前..");
                return Boolean.FALSE;   //审核前
            }
        }
        return approvedFlag;
    }


    /**实现流程方法匿名类**/
    class ResolveProcessParameters implements ResolveProcessParametersHandler{

        private ProcessParamBO processParamBO;
        private User logedUser;
        ResolveProcessParameters(ProcessParamBO processParamBO,User logedUser){
            this.processParamBO = processParamBO;
            this.logedUser = logedUser;
        }
        @Override
        public Map<String, Object> resolveParameters(List<ProcessVariable> requiredParameters) {
            Map<String, Object> resolveParameters = new HashMap<>(64);
            if (CollectionUtils.isNotEmpty(requiredParameters)) {
                for (ProcessVariable processVariable : requiredParameters) {

                    switch (processVariable.getId()) {
                        /**基础参数**/
                        //订单id
                        case Constant.ORDERID:
                            resolveParameters.put(processVariable.getId(), processParamBO.getBusinessKey());
                            break;
                        //业务类型
                        case Constant.BIZTYPE:
                            resolveParameters.put(processVariable.getId(), processParamBO.getBizType());
                            break;
                        //贷款金额
                        case Constant.LOANQUOTA:
                            resolveParameters.put(processVariable.getId(), processParamBO.getLoanMoney());
                            break;
                        //申请编号
                        case Constant.APPLYID:
                            resolveParameters.put(processVariable.getId(), processParamBO.getApplyId());
                            break;
                        //申请类型
                        case Constant.APPLYTYPE:
                            resolveParameters.put(processVariable.getId(), processParamBO.getApplyType());
                            break;
                        //是否需要安装GPS
                        case Constant.ISNEEDGPSINSTALLED:
                            resolveParameters.put(processVariable.getId(), processParamBO.getGpsFlag());
                            break;
                        //是否已垫款
                        case Constant.ISCASHINADVANCE:
                            resolveParameters.put(processVariable.getId(), processParamBO.getIsCashIn());
                            break;
                        //额度范围
                        case Constant.QUOTALIMIT:
                            Double quotaLimit = selectQuotaBySalesManager(logedUser);
                            resolveParameters.put(processVariable.getId(), quotaLimit);
                            break;
                        /**人员参数**/
                        //业务员id
                        case Constant.ROLESALESMANID:
                            resolveParameters.put(processVariable.getId(), processParamBO.getStaffId());
                            break;
                        default:
                            break;
                    }

                    /** 流程人员参数 **/
                    if(FlowRoleIdEnum.verify(processVariable.getId())){
                        randomExecutorByApproved(processParamBO.getApproved(), processVariable, resolveParameters, processVariable.getId(),logedUser);
                    }

                    /**审核意见**/

                    if(FlowApprovedEnum.verify(processVariable.getId())){
                        resolveParameters.put(processVariable.getId(), processParamBO.getApproved());
                    }

                }
            }
            log.info("流程包含参数：{}", JSON.toJSONString(resolveParameters));
            return resolveParameters;
        }
    }


    /**
     * 检查飘红规则
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public WanderResultVO checkWanderRules(User logedUser) throws SuzukiCommonException{
        log.info("正在验证飘红情况...");
        /**获取当前员工的部门**/
        Long deptId = logedUser.getDeptId();
        log.info("当前员工所属部门为：{},{}", deptId, logedUser.getDeptName());
        /**获取部门所属省份**/
        List<DeptArea> deptAreaList =  logedUser.getDeptBizAreaList();
        if(CollectionUtils.isEmpty(deptAreaList)){
            throw new SuzukiCommonException(ErrorCodeEnum.DEPT_AREA_ISNULL);
        }
        DeptArea deptArea = deptAreaList.get(0);
        log.info("当前员工所属省份为：{},{}", deptArea.getAreaId(), deptArea.getAreaName());
        /**根据省份查询所属部门**/
        log.info("正在查询{}部门...",deptArea.getAreaName());
        List<DeptBizAreaDTO> deptBizAreaDTOList =  staffDeptService.selectBizAreaDeptList(deptArea.getAreaId());
        log.info("部门列表：{}",deptBizAreaDTOList);
        if(deptBizAreaDTOList.isEmpty()) {
            log.error("查询{}列表错误...",deptArea.getAreaName());
            throw new SuzukiCommonException(ErrorCodeEnum.SELECT_FAILURE);
        }
        /**根据部门ID查询所属订单**/
        List<OrderInfoBO>  allOrderList = new ArrayList<>();    //具备条件的所有订单
        BigDecimal totalAmount = BigDecimal.ZERO;              //初始化贷款金额
        /**初始化时间**/
        DateRangeVO dateRangeVO = DateUtil.getLastMonth();
        for(int i = 0 ; i<deptBizAreaDTOList.size();i++){
            Map<String, Object> paramMap = new HashMap<>(64);
            paramMap.put("deptId",deptBizAreaDTOList.get(i).getDeptId());              //部门id
            paramMap.put("orderStatus",OrderStatusEnum.ALREADY_PAYMENT.getCode());    //订单状态为已垫款
            paramMap.put("gmtCreateBegin", dateRangeVO.getStart());                   //上月始
            paramMap.put("gmtCreateEnd",dateRangeVO.getEnd());                         //上月末
            log.info("正在查询已垫款的订单...");
            List<OrderInfoBO> orderInfoList = loanInfoExtMapper.selectOrderListByDeptId(paramMap);
            allOrderList.addAll(orderInfoList);
            /**根据订单计算总贷款金额**/
            for(int j = 0;j<orderInfoList.size();j++){
                BigDecimal loaningAmount = orderInfoList.get(j).getLoaningAmount();
                totalAmount = totalAmount.add(loaningAmount);
            }
        }
        log.info("订单数量为{}",allOrderList.size());
        log.info("含有订单{}",allOrderList);
        log.info("{}上个月订单贷款总额度为：{}", deptArea.getAreaName(), totalAmount);
        /**初始化飘红规则**/
        log.info("正在初始化飘红规则...");
        int wanderTotalCount = 0;       //允许总飘红个数
        boolean isCheckWanderRules = true;   //默认飘红规则
        BigDecimal defaultMoney = new BigDecimal("8000000.0000");   //默认金额
        if(defaultMoney.compareTo(totalAmount)!= -1){
            log.info("检测到贷款总额度小于800W...");
            wanderTotalCount = 1;
        }else{
            log.info("检测到贷款总额度大于等于800W...");
            wanderTotalCount = 2;
        }
        log.info("默认允许总飘红个数:{}", wanderTotalCount);
        List<String> wanderList = this.wanderByProvince(deptArea.getAreaId(),allOrderList);
        log.info("实际总飘红个数:{}", wanderList.size());
        if(wanderList.size()>wanderTotalCount){
            isCheckWanderRules = false;
        }
        WanderResultVO wanderResultVO = new WanderResultVO();
        wanderResultVO.setIsCheckWanderRules(isCheckWanderRules);
        wanderResultVO.setCollectWanderList(wanderList);
        return wanderResultVO;
    }


    /**
     * 查询业务经理拥有的贷款额度
     * @param logedUser
     * @return
     */
    public Double selectQuotaBySalesManager(User logedUser) throws SuzukiCommonException{
        /**获取当前业务员对应的业务经理**/
        Long deptId = logedUser.getDeptId();
        log.info("当前员工所属部门为：{},{}", deptId, logedUser.getDeptName());
        List<StaffRoleDTO> list = staffDeptService.selectStaffByDept(deptId,RoleTypeEnum.ROLE_SALESMANAGER.getCode());
        if (!CollectionUtils.isEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                Long staffId = list.get(i).getStaffId();
                log.info("当前业务经理ID为：{}", staffId);
                AuditQuotaDTO auditQuotaInfo = iAuditQuotaService.getAuditQuotaDetailByStaffId(staffId);
                if(auditQuotaInfo==null){
                    log.error("业务经理额度范围未设定...");
                    throw new SuzukiCommonException(ErrorCodeEnum.SALESMANAGER_AUDITQUOTA_EMPTY);
                }
                Double quotaAmount = auditQuotaInfo.getMaxQuotaAmount().doubleValue();
                log.info("当前额度为{}",quotaAmount);
                return quotaAmount;
            }
        }
        throw new SuzukiCommonException(ErrorCodeEnum.SELECT_FAILURE);
    }


    /**
     * 获取飘红订单号
     * @param paymentRequestVO
     * @return
     */
    public String wanderOrder(PaymentRequestVO paymentRequestVO){
        /**查询订单的合同信息**/
        log.info("正在查询订单{}的合同信息...",paymentRequestVO.getOrderNo());
        ContractSubmitQuery contractSubmitQuery = new ContractSubmitQuery();
        contractSubmitQuery.createCriteria().andOrderNoEqualTo(paymentRequestVO.getOrderNo()).andIsDeletedEqualTo(IsDeletedEnum.NORMAL.getCode());
        List<ContractSubmitDO> contractSubmitList = contractSubmitManager.selectByQuery(contractSubmitQuery);
        log.info("合同信息查询完成...");
        if(!contractSubmitList.isEmpty()){
            if(contractSubmitList.get(0).getCompleteDate()==null){
                /**若合同齐全日期为空，则属于飘红**/
                log.info("订单号{}合同齐全日期为空...",contractSubmitList.get(0).getOrderNo());
                return contractSubmitList.get(0).getOrderNo();
            }else {
                //不做操作,返回null
                return null;
            }
        }else{
            /**数据为空,则属于飘红**/
            log.info("订单号{}合同齐全数据为空...",paymentRequestVO.getOrderNo());
            return paymentRequestVO.getOrderNo();
        }
    }


    /**
     * 不同地区处理飘红情况
     * @param provinceId
     * @param allOrderList
     * @return
     */
    public  List<String> wanderByProvince(Long provinceId,List<OrderInfoBO>  allOrderList){
        List<String> collectWanderList = new ArrayList<>();      //飘红订单汇总
        /**根据省份id查询省份信息**/
        ProvinceQuery provinceQuery = new ProvinceQuery();
        provinceQuery.createCriteria().andProvinceIdEqualTo(provinceId);
        List<ProvinceDO> provinceDOList = provinceManager.selectByQuery(provinceQuery);
        if(provinceDOList.isEmpty()){
            throw new SuzukiCommonException(ErrorCodeEnum.SELECT_FAILURE);
        }
        /**allOrderList-- 所有订单状态为已垫款的订单**/
        for(int i=0;i<allOrderList.size();i++){
            /**获取订单财务垫款时间**/
            log.info("正在查询订单号{}财务垫款申请数据...",allOrderList.get(i).getOrderNo());
            PaymentRequestVO paymentRequestVO = paymentRequestService.getPaymentRequest(allOrderList.get(i).getOrderNo());
            if(paymentRequestVO == null){
                throw new SuzukiCommonException(ErrorCodeEnum.PAYMENT_REQUEST_ISNULL);
            }
            /**财务已垫款时间与当前时间比较**/
            LocalDateTime loaningDate = paymentRequestVO.getLoaningDate();    //财务垫款时间
            LocalDateTime  nowTime = LocalDateTime.now();   //当前时间
            Duration duration = Duration.between(loaningDate,nowTime);
            log.info("垫款时间和当前时间相差:{}天", duration.toDays());
            if(Constant.SHANGHAI.equals(provinceDOList.get(0).getProvinceName())
                    || Constant.JIANGSHU.equals(provinceDOList.get(0).getProvinceName())
                    || Constant.ZHEJIANG.equals(provinceDOList.get(0).getProvinceName())){
                if(duration.toDays() > 3){
                    /**当省份地区为江浙沪,大于3天，则飘红**/
                    log.info("已飘红(江浙沪地区)");
                    String wanderOrder = this.wanderOrder(paymentRequestVO);
                    if(StringUtils.isBlank(wanderOrder)){
                        continue;
                    }
                    collectWanderList.add(wanderOrder);
                }
            }else if(Constant.XINJIANG.equals(provinceDOList.get(0).getProvinceName())){
                if(duration.toDays() > 5){
                    /**新疆地区大于5天，则飘红**/
                    String wanderOrder = this.wanderOrder(paymentRequestVO);
                    if(StringUtils.isBlank(wanderOrder)){
                        continue;
                    }
                    collectWanderList.add(wanderOrder);
                }
            }else{
                if(duration.toDays() > 4){
                    /**其他大于4天，则飘红**/
                    String wanderOrder = this.wanderOrder(paymentRequestVO);
                    if(StringUtils.isBlank(wanderOrder)){
                        continue;
                    }
                    collectWanderList.add(wanderOrder);
                }
            }
        }
        return collectWanderList;
    }


    /**
     * 审核分配原则
     * @param roleCodeStr
     * @param logedUser
     * @return
     * @throws SuzukiCommonException
     */
    private String randomExecutor(String roleCodeStr,User logedUser) throws SuzukiCommonException {
        /**截取字符串获取角色名称**/
        log.info("开始截取角色名称...");
        String newStr = roleCodeStr.substring(4, roleCodeStr.indexOf("Id"));
        String roleCode = "ROLE_" + newStr.toUpperCase();
        log.info("开始分配任务,下个节点执行角色为：{}", roleCode);
        /**当角色是业务经理**/
        if(RoleTypeEnum.ROLE_SALESMANAGER.getCode().equals(roleCode)){
            /**获取当前用户的部门信息**/
            Long deptId = logedUser.getDeptId();
            log.info("当前员工角色为：{},所在部门为：{}--{}", logedUser.getRoleList().get(0), logedUser.getDeptId(), logedUser.getDeptName());
            log.info("正在查询所属业务经理...");
            List<StaffRoleDTO> salesManagerList = staffDeptService.selectStaffByDept(deptId,RoleTypeEnum.ROLE_SALESMANAGER.getCode());
            if(CollectionUtils.isEmpty(salesManagerList)){
                log.error("查不到对应的业务经理...");
                throw new SuzukiCommonException(ErrorCodeEnum.SALESMANAGER_LIST_ERROR);
            }
            log.info("当前业务员所属业务经理为:{}--{}",salesManagerList.get(0).getStaffId(),salesManagerList.get(0).getStaffName());
            return String.valueOf(salesManagerList.get(0).getStaffId());
        }
        /**当角色是审核员**/
        else if(RoleTypeEnum.ROLE_AUDITOR.getCode().equals(roleCode)){
            log.info("正在查询审核员列表...");
            List<StaffRoleDTO> auditorList = staffRoleService.selectStaffByRole(roleCode);
            log.info("当前角色下拥有执行人信息如下：{}", JSON.toJSONString(auditorList));
            if(CollectionUtils.isEmpty(auditorList)){
                log.error("查不到审核员列表...");
                throw new SuzukiCommonException(ErrorCodeEnum.AUDITOR_LIST_ERROR);
            }
            /**获取及赋值suzuki_indexCount**/
            int indexCount = this.getIndexOfList();
            int index  = indexCount % (auditorList.size());
            log.info("当前获取下标为{}",index);
            /**根据缓存的index值获取执行人**/
            String approveStaffId = String.valueOf(auditorList.get(index).getStaffId());
            /**将indexCount加1缓存到redis里**/
            redisTemplate.opsForValue().set("suzuki_indexCount",indexCount+1);
            return approveStaffId;
        }
        /**其他**/
        else{
            log.info("正在查询{}列表",roleCode);
            List<StaffRoleDTO> list = staffRoleService.selectStaffByRole(roleCode);
            log.info("当前角色下拥有执行人信息如下：{}", JSON.toJSONString(list));
            if (CollectionUtils.isEmpty(list)) {
                log.error("查不到执行人列表...");
                throw new SuzukiCommonException(ErrorCodeEnum.OTHER_LIST_ERROR);
            }
            log.info("当前角色下包含{}名员工...", list.size());
            log.info("执行以少分配原则开始分配任务...");
            /**分别查询每人目前所处理的任务数**/
            String approveStaffId = null;
            int minCount = Integer.MAX_VALUE;    //初始值为最大
            for (int i = 0; i < list.size(); i++) {
                int count = orderAuditTaskExtMapper.countByTaskNum(list.get(i).getStaffId());
                if (count < minCount) {
                    minCount = count;
                    approveStaffId = String.valueOf(list.get(i).getStaffId());
                }
            }
            log.info("分配任务结束，执行人编号为：{}", approveStaffId);
            return approveStaffId;
        }
    }



    /**
     * 保存获取执行人次数
     * 用于审核员
     * @return
     */
    @Cacheable(value="suzuki_indexCount")
    public int getIndexOfList(){
        if(redisTemplate.hasKey("suzuki_indexCount")){
            /**如果存在，则直接取**/
            return  Integer.parseInt(redisTemplate.opsForValue().get("suzuki_indexCount").toString());
        }else{
            /**如果不存在，则直接默认赋值0**/
             int indexCount = 0;
             redisTemplate.opsForValue().set("suzuki_indexCount",indexCount);
             return indexCount;
        }
    }

}
